package jun.cli;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.util.Iterator;

import jun.comm.netkit.JunProtocol;

public class TestCli3 {

	// 要连接的服务器Ip地址
	private static String IP = "127.0.0.1";

	// 要连接的远程服务器在监听的端口
	private static int PORT = 50080;

	// 信道选择器
	private static Selector selector;

	// 与服务器通信的信道
	private static SocketChannel sktChan;

	public static void main(String[] args) throws IOException {
		// 打开监听信道
		sktChan = SocketChannel.open(new InetSocketAddress(IP, PORT));
		// 设置为非阻塞模式
		sktChan.configureBlocking(false);

		// 创建选择器
		selector = Selector.open();
		// 注册选择器到信道
		sktChan.register(selector, SelectionKey.OP_WRITE);

		if (selector.isOpen() && selector.select() > 0) {
			// 创建一个处理协议的实现类,由它来具体操作
			JunProtocol junProtocol = new JunProtocol();

			// 取得迭代器.selectedKeys()中包含了每个准备好某一I/O操作的信道的SelectionKey
			Iterator<SelectionKey> keyIter = selector.selectedKeys().iterator();

			while (keyIter.hasNext()) {
				SelectionKey key = keyIter.next();

				try {
					if (key.isValid() && key.isWritable()) {
						// 客户端可写时
						junProtocol.write(key, "你好!Nio!醉里挑灯看剑,梦回吹角连营");
					}
				} catch (Exception e) {
					// 出现IO异常（如客户端断开连接）时移除处理过的键
					keyIter.remove();
					continue;
				}

				// 移除处理过的键
				keyIter.remove();
			}
		}
		
		
		// 注册选择器到信道
		sktChan.register(selector, SelectionKey.OP_READ);
		if (selector.isOpen() && selector.select() > 0) {
			// 创建一个处理协议的实现类,由它来具体操作
			JunProtocol junProtocol = new JunProtocol();

			// 取得迭代器.selectedKeys()中包含了每个准备好某一I/O操作的信道的SelectionKey
			Iterator<SelectionKey> keyIter = selector.selectedKeys().iterator();

			while (keyIter.hasNext()) {
				SelectionKey key = keyIter.next();

				try {
					if (key.isReadable()) {
						// 从客户端读取数据
						junProtocol.read(key);
					}
				} catch (Exception e) {
					// 出现IO异常（如客户端断开连接）时移除处理过的键
					keyIter.remove();
					continue;
				}

				// 移除处理过的键
				keyIter.remove();
			}
		}


	}

}
